import { Button, Card, Drawer, Form, Input, Select, Space, Switch, Affix, App, TreeSelect } from "antd";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import type { GetProp, TreeSelectProps } from 'antd';
import { IconSelector } from "./IconSelector";
import { LibAppView } from "../../../../lib";
import Api from "../../Api";
import lodash from "lodash";
import { AdminRight, useAdminRight } from "@/pages/Admin/data/AdminPageAuth";

interface ISelectOption {
    label: string|React.ReactNode;
    value: any;
}
type DefaultOptionType = GetProp<TreeSelectProps, 'treeData'>[number];


const FormItemWrapper = ({ onChange, onItemChange, ...others }: any) => {
    const onChildrenChange = useCallback((...args: any[]) => {
        typeof onChange === "function" && onChange(...args);
        typeof onItemChange === "function" && onItemChange(...args);
    }, [onChange, onItemChange])
    return React.cloneElement(others.children, {
        ...others,
        onChange: onChildrenChange
    });
};

const Edit = () => {
    const app = LibAppView.useApp();
    const microApp = LibAppView.useMicroApp();
    const antApp = App.useApp();
    const intl = useIntl();
    const api = Api.useApi();
    const journeyData = LibAppView.useJourneyData();
    const editData = journeyData.currentStepState || {};
    const hasEditRight = useAdminRight("editable");
    const [ form ] = Form.useForm();
    const [ componentDisabled, setComponentDisabled] = useState(!hasEditRight);
    const [ selectedModule, setSelectedModule ] = useState();
    const [ defaultFormData ] = useState({
        ...editData,
        parentId: editData.parent_id || 0,
        module: editData.module || "Admin",
        id: editData.id || null,
        name: editData.name || "",
        pathname: editData.pathname || "",
        icon: editData.icon || "",
        status: editData.status === 1
    });
    const [ parentList, setParentList ] = useState<Omit<DefaultOptionType, 'label'>[]>([
        { title: <FormattedMessage id="admin.pages.menus.edit.firstLevel"/>, value: 0, pId: 0, id: -1 }
    ]);
    const [ moduleList ] = useState<ISelectOption[]>([
        { label: <FormattedMessage id="admin.pages.menus.edit.module.admin"/>, value: "Admin" },
        { label: <FormattedMessage id="admin.pages.menus.edit.module.blog"/>, value: "Blog" },
        { label: <FormattedMessage id="admin.pages.menus.edit.module.web"/>, value: "Web" },
        { label: <FormattedMessage id="admin.pages.menus.edit.module.wechat"/>, value: "Wechat" }
    ]);
    const onSubmit = useCallback(() => {
        const formData = form.getFieldsValue();
        formData.status = formData.status ? 1 : 0;
        setComponentDisabled(true);
        app.serviceApi.send({
            endPoint: "menus.submit",
            data: {
                ...formData,
                id: defaultFormData.id,
                sortId: formData.sortId || 0
            }
        }).then(() => {
            setComponentDisabled(false);
            antApp.message.success(intl.formatMessage({ id: "admin.pages.form.submit.success", defaultMessage: "Submit successfully."}));
            api.refreshMenu();
        }).catch((err) => {
            setComponentDisabled(false);
            antApp.message.error(err.message);
        });
    }, [defaultFormData]);
    const onRefreshStrctList = useCallback((parentId: number=0) => {
        return new Promise((resolve, reject) => {
            app.serviceApi.send({
                endPoint: "menus.structList",
                data: {
                    parentId,
                    module: form.getFieldValue("module")
                }
            }).then(({ data }: any) => {
                const listData = data || [];
                resolve(listData.map((item: any) => {
                    return {
                        id: item.id,
                        title: intl.formatMessage({ id: item.name, defaultMessage: item.name}),
                        pId: parentId,
                        value: item.id
                    }
                }));
            }).catch((err) => {
                antApp.message.error(err.message);
                reject(err);
            });
        });
    }, []);
    const onLoadData= useCallback(({ id }: any) => {
        return new Promise((resolve, reject) => {
            onRefreshStrctList(id).then((newListData: any) => {
                const updateListData = [...parentList, ...newListData];
                console.log(updateListData);
                setParentList(updateListData);
                resolve({});
            }).catch(reject);
        });
    }, [parentList]);
    useEffect(() => {
        onRefreshStrctList().then((listData) => {
            setParentList([
                { title: <FormattedMessage id="admin.pages.menus.edit.firstLevel"/>, value: 0, pId: 0, id: -1, isLeaf: true },
                ...(listData as any[])
            ]);
        }).catch((err) => console.error(err));
    }, []);
    useEffect(() => {
        if(!lodash.isEmpty(selectedModule)) {
            onRefreshStrctList().then((listData) => {
                setParentList([
                    { title: <FormattedMessage id="admin.pages.menus.edit.firstLevel"/>, value: 0, pId: 0, id: -1, isLeaf: true },
                    ...(listData as any[])
                ]);
            }).catch((err) => console.error(err));
        }
    }, [selectedModule, onRefreshStrctList, moduleList]);
    return (
     <Card style={{ width: "100%", minHeight: "76vh", padding: 20 }}>
        <Form
            labelCol={{ span: 5 }}
            wrapperCol={{ span: 12 }}
            layout="horizontal"
            disabled={componentDisabled}
            form={form}
            initialValues={defaultFormData}
        >
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.module" />}
                name="module"
            >
                <FormItemWrapper onItemChange={(value: any) => setSelectedModule(value)}>
                    <Select options={moduleList}  />
                </FormItemWrapper>
            </Form.Item>
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.parent" />}
                name="parentId"
            >
                <TreeSelect
                    treeDataSimpleMode
                    style={{ width: '100%' }}
                    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                    placeholder="Please select"
                    loadData={onLoadData}
                    treeData={parentList}
                />
            </Form.Item>
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.title" />}
                name="name"
            >
                <Input type="text" autoComplete="off"/>
            </Form.Item>
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.pathname" />}
                name="pathname"
            >
                <Input type="text" autoComplete="off" />
            </Form.Item>
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.icon" />}
                name="icon"
            >
                <IconSelector />
            </Form.Item>
            <Form.Item
                label={<FormattedMessage id="admin.pages.menus.edit.status" />}
                name="status"
            >
                <Switch
                    checkedChildren={<FormattedMessage id="admin.pages.menus.edit.status.enable" />}
                    unCheckedChildren={<FormattedMessage id="admin.pages.menus.edit.status.disable" />}
                />
            </Form.Item>
            <Form.Item
                label={"排序"}
                name="sortId"
            >
                <Input type="number" />
            </Form.Item>
            <Form.Item wrapperCol={{ offset: 5, span: 16 }}>
                <Button loading={hasEditRight && componentDisabled} type="primary" htmlType="submit" onClick={onSubmit}>
                    <FormattedMessage id="admin.pages.form.submit" />
                </Button>
                <Button disabled={false} style={{marginLeft: 10}} type="default" onClick={() => {
                    microApp.goBack();
                }}>
                    <FormattedMessage id="admin.pages.form.back" />
                </Button>
            </Form.Item>
        </Form>
    </Card>
    );
};

export default Edit;
